//
// Created by F1997 on 2024/10/21.
//

#ifndef NETWORK_TRAFFIC_PROCESSING_COMPARETRAFFIC_H
#define NETWORK_TRAFFIC_PROCESSING_COMPARETRAFFIC_H



#include "../utils/pch.h"
#include "../utils/IniReader.h"
#include "../utils/ThreadPoolV2.hpp"

// 对比两路流量快慢
class CompareTraffic {
public:
    // 初始化
    CompareTraffic() {

        // 创建消息队列 = 1
        int key1 = ftok("msg_queue_keyfile1", 65); // 根据文件生成key
        int key = 1234;
        // 如何调整队列大小
        msgid1 = msgget(key, 0666 | IPC_CREAT); // 0666 | IPC_CREAT = 权限和msg标记位。用户读写、组读写（660）。0666
        if (msgid1 == -1) {
            perror("msgget");
            exit(1);
        }
        // 设置消息队列的状态
        struct msqid_ds ds;
        msgctl(msgid1, IPC_STAT, &ds); // 获取消息队列状态

        ds.msg_qbytes = 15 * 1024 * 1024; // 设置消息队列的最大字节为 10MB
        msgctl(msgid1, IPC_SET, &ds); // 设置消息队列的属性

        printf("line 1 Message queue size set to %ld bytes\n", ds.msg_qbytes);


        // 创建消息队列 = 2
        int key2 = 5678;
        // 如何调整队列大小
        msgid2 = msgget(key2, 0666 | IPC_CREAT); // 0666 | IPC_CREAT = 权限和msg标记位。用户读写、组读写（660）。0666
        if (msgid2 == -1) {
            perror("msgget");
            exit(1);
        }
        // 设置消息队列的状态
        struct msqid_ds ds2;
        msgctl(msgid2, IPC_STAT, &ds2); // 获取消息队列状态

        ds.msg_qbytes = 15 * 1024 * 1024; // 设置消息队列的最大字节为 10MB
        msgctl(msgid2, IPC_SET, &ds2); // 设置消息队列的属性

        printf("line 2 Message queue size set to %ld bytes\n", ds.msg_qbytes);

/*        // 设置消息队列的属性
        attr.mq_flags = 0;       // 标志位，通常设为0
        attr.mq_maxmsg = 10;     // 队列中最多的消息数
        attr.mq_msgsize = 256;   // 单个消息的最大字节数
        attr.mq_curmsgs = 0;     // 当前队列中的消息数，初始化为0*/

        p_t = new ThreadPool(2);

    }
    // 队列为空
    ~CompareTraffic() = default;

    bool checkIsStart(int offset);
    void writeTraffic1(struct pcap_pkthdr header);
    void writeTraffic2(struct pcap_pkthdr header);
    void readTraffic1(std::shared_ptr<spdlog::logger> my_logger);

    std::string timevalToString(const struct timeval& tv);
    std::string timevalToString2(const struct timeval& tv);

    void contrast(const char *msg1, const char *msg2, std::shared_ptr<spdlog::logger> my_logger, int i, int j);
    void sampledAndSave(std::shared_ptr<spdlog::logger> my_logger);


private:
    // 消息结构体，必须含 msg_type ，msg，msg只有1个？？？
    struct msg_buffer {
        long msg_type; // 消息类型，行情类型
        char msg[100]; // 包编号
        char msg2[100]; // 时间戳
    };

    // 内置的消息队列属性结构体
    //struct mq_attr attr;


    // 行情1到达包的计数器
    int Line1PkgCount = 0;
    // 行情2到达的计数器
    int Line2PkgCount = 0;

    // 行情1先到包的计数器
    //int Line1Count = 0;
    //std::atomic<int> Line1Count = 0;
    // 行情2先到包的计数器
    //int Line2Count = 0;
    //std::atomic<int> Line2Count = 0;

    //std::atomic<int> atm2(0);
    //std::atomic<int> atm = 0; // 初始化一个原子整数为 0


    int msgid1; // 队列1
    int msgid2; // 队列2


    // 为什么不能加互斥锁？？？
    // 互斥锁和条件变量
    //std::mutex mtx;
    //std::condition_variable cv;
    //bool ready_to_read = false;

    IniReader* iniCfg;

    ThreadPool* p_t;

};



#endif //NETWORK_TRAFFIC_PROCESSING_COMPARETRAFFIC_H
